library(tidyverse)
library(estimatr)
library(ggthemes)
library(kableExtra)
options(knitr.table.format = "latex")
library(texreg)
library(multcomp)
library(ltm)
select <- dplyr::select

load("output/cleaned_data.Rdata")

source("functions/estimate_means.R")
source("functions/visualize_means.R")
source("functions/make_texreg.R")
source("functions/make_kable.R")

# insert your own save_path to directory to directly port over tables/figures
# save_path <- 

build_summary <- function(.data){
  out <- as.data.frame(round(apply(.data, 2, mean, na.rm = TRUE), digits = 3)) %>% 
    cbind(round(apply(.data, 2, sd, na.rm = TRUE), digits = 3)) %>% 
    cbind(round(apply(.data, 2, min, na.rm = TRUE), digits = 3)) %>% 
    cbind(round(apply(.data, 2, max, na.rm = TRUE), digits = 3)) %>% 
    as.data.frame() %>% 
    rownames_to_column() %>% 
    `colnames<-`(c("Variable", "Mean", "SD", "Min", "Max"))
}

# Main--------------------- ---------------------------------------------------
# Figure 1 (Frequency and Severity Combined, Study 1A) -------------------------------------------------

dfact2020 <- estimate_means(df_fact, "subgroup_nowave", Party) |> 
  filter(!is.na(Party))
dabstract2020 <- estimate_means(df_abstract, "subgroup_nowave", Party) |> 
  filter(!is.na(Party))
dall2020 <- rbind(dfact2020, dabstract2020)

visualize_means(dall2020, "by_party")

ggsave(paste0(save_path, "figures/combined_study1a.png"),
       width = 8, height = 6)


# Analysis for Study 1A ---------------------------------------------------

# Facts Analysis

## Each error is different BETWEEN parties, p < .01
df_fact %>% 
  filter(!is.na(Party) & fact_dv == "Main") |> 
  group_by(Error) %>% 
  summarise(tidy(lm_robust(fact_values ~ Party, clusters = ResponseId, data = cur_data())), 
            .groups = "drop")

## Each error is different WITHIN parties, except for uncounted and forgone for Dems (p = .7)
## and uncounted and fraudulent for Reps (p = .6)
df_fact %>% 
  filter(!is.na(Party) & fact_dv == "Main") |> 
  group_by(Party) |> 
  summarise(tidy(lm_robust(fact_values ~ Error, clusters = ResponseId, data = cur_data())), 
            .groups = "drop")

# Seriousness Analysis

## Each error is different BETWEEN parties, p < .01
df_abstract %>% 
  filter(!is.na(Party) & abstract_dv == "Main") |> 
  group_by(Error) %>% 
  summarise(tidy(lm_robust(abstract_values ~ Party, clusters = ResponseId, data = cur_data())), 
            .groups = "drop")

## Each error is different WITHIN parties, except for uncounted and forgone for Dems (p = .7)
## and uncounted and fraudulent for Reps (p = .6)
df_fact %>% 
  filter(!is.na(Party) & fact_dv == "Main") |> 
  group_by(Party) |> 
  summarise(tidy(lm_robust(fact_values ~ Error, clusters = ResponseId, data = cur_data())), 
            .groups = "drop")


# Figure 2 (Frequency and Severity Combined, Study 1B) ----------------

dfact_partywave_2024 <- estimate_means(dfR_fact, "subgroup_nowave", Party, weight) |> 
  mutate(Wave = "2024")
dabstract_partywave_2024 <- estimate_means(dfR_abstract, "subgroup_nowave", Party, weight) |> 
  mutate(Wave = "2024")
dall2024 <- rbind(dfact_partywave_2024, dabstract_partywave_2024)

visualize_means(dall2024, "by_party")

ggsave(paste0(save_path, "figures/combined_study1b.png"),
       width = 8, height = 6)


# Analysis for Study 1B ---------------------------------------------------

dfR_fact |> 
  filter(!is.na(Party) & fact_dv == "Main") |> 
  group_by(Error) %>% 
  summarise(tidy(lm_robust(fact_values ~ Party, data = cur_data(), cluster = ResponseId,
                           weights = weight)), 
            .groups = "drop")

dfR_fact |> 
  filter(!is.na(Party) & fact_dv == "Main") |> 
  summarise(tidy(lm_robust(fact_values ~ Error, data = cur_data(), cluster = ResponseId,
                           weights = weight)), 
            .groups = "drop")

dfR_abstract |> 
  filter(!is.na(Party) & abstract_dv == "Main") |> 
  group_by(Error) %>% 
  summarise(tidy(lm_robust(abstract_values ~ Party, data = cur_data(),
                           weights = weight)), 
            .groups = "drop")


dfR_abstract |> 
  filter(!is.na(Party) & abstract_dv == "Main") |> 
  group_by(Party) %>% 
  summarise(tidy(lm_robust(abstract_values ~ Error, data = cur_data(),
                           weights = weight)), 
            .groups = "drop")


# Table 4 (Study 2A) -----------------------------------------------

lm2020_scenarios_democrat <- lm_robust(scenario_values ~ -1 + Error, clusters = ResponseId,
                                       subset = Party == "Democrat" & `Party Benefiting` == "Opposite Party" & scenario_dv == "feel_outraged", data = df_scenarios)

lm2020_scenarios_republican <- lm_robust(scenario_values ~ -1 + Error, clusters = ResponseId,
                                         subset = Party == "Republican" & `Party Benefiting` == "Opposite Party" &  scenario_dv == "feel_outraged", data = df_scenarios)

#texreg(list(lm2020_scenarios_democrat, lm2020_scenarios_democrat_noc), include.ci = FALSE, digits =6)


make_texreg("table_study2a",
            list(lm2020_scenarios_democrat, lm2020_scenarios_republican),
            stars = numeric(0),
            custom.model.names = c("Democrat", "Republican"),
            custom.coef.map = list("ErrorUncounted" =  "Uncounted Votes",
                                   "ErrorFraudulent" =  "Fraudulent Votes",
                                   "ErrorForgone" =  "Forgone Votes",
                                   "(Intercept)" = "Constant"),
            caption = "Mean Seriousness of Vignette when Election Error Hurts Own Party, Study 2A (2020)",
            refresh = TRUE,
            custom.note = paste("\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable is feelings of outrage, which ranges from 0--1. Models estimated 
            using ordinary least squares regression, 
            with robust standard errors clustered by respondent. 
            An election error hurts one's own party when uncounted votes get rid of cast votes for own party candidates,
                                fraudulent votes are counted for opposite party candidates, 
                                and forgone voters are unable to vote for their own party candidates."))


summary(lm_robust(scenario_values ~ Error,
          subset = Party == "Democrat" & `Party Benefiting` == "Opposite Party" & scenario_dv == "feel_outraged", data = df_scenarios))

summary(lm_robust(scenario_values ~ Error, clusters = ResponseId,
                  subset = Party == "Republican" & `Party Benefiting` == "Opposite Party" & scenario_dv == "feel_outraged", data = df_scenarios))

summary(lm_robust(scenario_values ~ Error*Party, clusters = ResponseId,
                  subset = `Party Benefiting` == "Opposite Party" & scenario_dv == "feel_outraged", data = df_scenarios))

# Table 5 (Study 2B) -----------------------------------------------



lm2024_scenarios_democrat <- lm_robust(vignette_dv ~ -1 + vignette_error, weights = weight,
                                       subset = Party == "Democrat" & error_hurt == 1, data = dfR)

lm2024_scenarios_republican <- lm_robust(vignette_dv ~ -1 + vignette_error, weights = weight,
                                         subset = Party == "Republican" & error_hurt == 1, data = dfR)

#texreg(list(lm2024_scenarios_democrat, lm2024_scenarios_republican), include.ci = FALSE, digits =3)


make_texreg("table_study2b",
            list(lm2024_scenarios_democrat, lm2024_scenarios_republican),
            stars = numeric(0),
            custom.model.names = c("Democrat", "Republican"),
            custom.coef.map = list("vignette_errorUncounted" =  "Uncounted Votes",
                                   "vignette_errorFraudulent" =  "Fraudulent Votes",
                                   "vignette_errorForgone" =  "Forgone Votes",
                                   "(Intercept)" = "Constant"),
            caption = "Mean Seriousness of Vignette when Election Error Hurts Own Party, Study 2B (2024)",
            refresh = TRUE,
            multiple.tasks = "normal",
            custom.note = paste("\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable is a combined measure of how wrong or serious the election error in the vignette was, which ranges from 0--1. Models estimated 
            using ordinary least squares regression, 
            with robust standard errors. 
            An election error hurts one's own party when uncounted votes get rid of cast votes for own party candidates,
                                fraudulent votes are counted for opposite party candidates, 
                                and forgone voters are unable to vote for their own party candidates."))


## Difference in election errors, Democrats (baseline forgone)
summary(lm_robust(vignette_dv ~  vignette_error, weights = weight,
          subset = Party == "Democrat" & error_hurt == 1, data = dfR))

## Difference in election errors, Republicans (baseline forgone)
summary(lm_robust(vignette_dv ~  vignette_error, weights = weight,
                  subset = Party == "Republican" & error_hurt == 1, data = dfR |> 
                    mutate(vignette_error = relevel(factor(vignette_error), ref = "Fraudulent"))))

# Table 6 (Study 3, Main) -------------------------------------------------

lm1_choice <- lm_robust(choice ~ fraudgap + disqualifiedgap + turnoutgap + vignette + Party,
                        data = df3a_conjoint,
                        clusters = ResponseId)

lm1_choice_interactions <- lm_robust(choice ~ fraudgap*Party + disqualifiedgap*Party + turnoutgap*Party + vignette,
                                     data = df3a_conjoint,
                                     clusters = ResponseId)

lm2_choice <- lm_robust(choice ~ fraudgap + disqualifiedgap + vignette + Party,
                        data = df3b_conjoint,
                        clusters = ResponseId)

lm2_choice_interactions <- lm_robust(choice ~ fraudgap*Party + disqualifiedgap*Party + vignette,
                                     data = df3b_conjoint,
                                     clusters = ResponseId)

texreg(list(lm1_choice, lm1_choice_interactions, 
            lm2_choice, lm2_choice_interactions), include.ci = FALSE, digits = 3)

make_texreg("table_study3",
            list(lm1_choice, lm1_choice_interactions, lm2_choice, lm2_choice_interactions),
            custom.header = list("Study 3A" = 1:2, "Study 3B" = 3:4),
            scalebox = 1,
            custom.model.names = c("Base", "Interactions", "Base", "Interactions"),
            custom.coef.map = list("fraudgap" = "Difference in Fraudulent Votes", 
                                   "disqualifiedgap" = "Difference in Uncounted Votes",
                                   "turnoutgap" = "Difference in Turnout", 
                                   "vignette2" = "Vignette Order (2nd Vignette)",
                                   "vignette3" = "Vignette Order (3rd Vignette)",
                                   "vignette4" = "Vignette Order (4th Vignette)",
                                   "vignette5" = "Vignette Order (5th Vignette)",
                                   "PartyRepublican" = "Republican",
                                   "fraudgap:PartyRepublican" = "Fraudulent $\\times$ Republican", 
                                   "PartyRepublican:disqualifiedgap" = "Uncounted $\\times$ Republican",
                                   "PartyRepublican:turnoutgap" = "Turnout $\\times$ Republican",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Difference in Election Errors on Choice of Election Rules, Study 3",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} Dependent variable is a binary 0 or 1, with 
                                1 as choosing the new election rule. 
       Models estimated using ordinary least squares regression, 
            with standard errors clustered by respondent."))


# Appendix--------------------- ---------------------------------------------------


# Section B: Survey Sample and Randomization-------- ------------------------------------
# Table B2 (Study 2A Summary Statistics) ----------------------------------------------------------------
summ_study2a <- df_scenarios %>% 
  filter(scenario_dv == "feel_outraged") %>% 
  mutate(`Feel Outraged` = scenario_values,
         `Wave (Pre)` = case_when(Wave == "Pre" ~ 1,
                                  TRUE ~ 0),
         `Wave (During)` = case_when(Wave == "During" ~ 1,
                                     TRUE ~ 0),
         `Wave (Post)` = case_when(Wave == "Post" ~ 1,
                                   TRUE ~ 0),
         `Party (Republican = 1, Democrat = 0)` = case_when(Party == "Republican" ~ 1,
                                                            Party == "Democrat" ~ 0),
         `Party Benefiting (Opposite = 1, Own = 0)` = case_when(`Party Benefiting` == "Opposite Party" ~ 1,
                                                                TRUE ~ 0),
         `Intention (Villain = 1, No Villain = 0)` = case_when(Intention == "Villain" ~ 1,
                                                               Intention == "No Villain" ~ 0),
         `Error (Fraudulent)` = case_when(Error == "Fraudulent" ~ 1,
                                          TRUE ~ 0),
         `Error (Uncounted)` = case_when(Error == "Uncounted" ~ 1,
                                         TRUE ~ 0),
         `Error (Forgone)` = case_when(Error == "Forgone" ~ 1,
                                       TRUE ~ 0),
         `Type (Mail = 1, In-Person = 0)` = case_when(Type == "Mail" ~ 1,
                                                      Type == "In-Person" ~ 0)) %>% 
  select(-c(ResponseId:Type)) %>% 
  build_summary()

make_kable(summ_study2a,
           col.names = names(summ_study2a),
           caption = "Summary Statistics for Study 2A")



# Table B3 (Study 2B Summary Statistics) -----------------------------------------------------

summ_study2b <- dfR %>% 
  mutate(`Dependent Variable` = vignette_dv,
         `Party (Republican = 1, Democrat = 0)` = case_when(Party == "Republican" ~ 1,
                                                            Party == "Democrat" ~ 0),
         `Error (Fraudulent)` = case_when(vignette_error == "Fraudulent" ~ 1,
                                          TRUE ~ 0),
         `Error (Uncounted)` = case_when(vignette_error == "Uncounted" ~ 1,
                                         TRUE ~ 0),
         `Error (Forgone)` = case_when(vignette_error == "Forgone" ~ 1,
                                       TRUE ~ 0),
         `Party Benefiting (Trump)` = case_when(vignette_support == "Trump" ~ 1,
                                                TRUE ~ 0),
         `Party Benefiting (Biden)` = case_when(vignette_support == "Biden" ~ 1,
                                                TRUE ~ 0),
         `Party Benefiting (Unspecified)` = case_when(vignette_support == "None" ~ 1,
                                                      TRUE ~ 0),
         `DV Wording (Serious = 1, Wrong = 0)` = case_when(vignette_wording == "wrong" ~ 1,
                                                           TRUE ~ 0)) |> 
  select(-c(ResponseId:error_hurt)) %>% 
  build_summary()

make_kable(summ_study2b,
           col.names = names(summ_study2b),
           caption = "Summary Statistics for Study 2B")


# Table B4 (Study 3A Summary Statistics) ----------------------------------------------------------------

summ_study3a <- df3a_conjoint %>% 
  mutate(`Election Plan Choice` = choice,
         `Election Plan Rating` = fair,
         `Difference in Fraudulent Votes` = fraudgap,
         `Difference in Uncounted Votes` = disqualifiedgap,
         `Difference in Turnout` = turnoutgap,
         `Vignette` = vignette,
         `Republican` = case_when(Party == "Republican" ~ 1,
                                  Party == "Democrat" ~ 0),
         `Fraudulent Votes` = fraud,
         `Uncounted Votes` = disqualified,
         `Turnout` = turnout) %>% 
  select(-c(ResponseId:disqualified)) %>% 
  mutate(across(everything(),
                ~ as.numeric(.x))) %>% 
  build_summary()

make_kable(summ_study3a,
           col.names = names(summ_study3a),
           caption = "Summary Statistics for Study 3A")


# Table B5 (Study 3A Summary Statistics) ----------------------------------------------------------------

summ_study3b <- df3b_conjoint %>% 
  mutate(`Election Plan Choice` = choice,
         `Election Plan Rating` = rules1,
         `Difference in Fraudulent Votes` = fraudgap,
         `Difference in Uncounted Votes` = disqualifiedgap,
         `Vignette` = vignette,
         `Republican` = case_when(Party == "Republican" ~ 1,
                                  Party == "Democrat" ~ 0),
         `Fraudulent Votes` = fraud,
         `Uncounted Votes` = disqualified) %>% 
  select(-c(ResponseId:rules5)) %>% 
  mutate(across(everything(),
                ~ as.numeric(.x))) %>% 
  build_summary()

make_kable(summ_study3b,
           col.names = names(summ_study3b),
           caption = "Summary Statistics for Study 3B")


# Section C: Study 1 Additional Analysis-------- ------------------------------------


# Figure C1: Facts Panel by Party/Wave  -----------------------------------

dfact_partywave_2020 <- estimate_means(df_fact, "did")


visualize_means(dfact_partywave_2020, "did")

ggsave(paste0(save_path, "figures/fact_partisan_wave_2020.png"),
       width = 8, height = 4)

# Figure C2: Abstract Panel by Party/Wave  -----------------------------------


dabstract_partywave_2020 <- estimate_means(df_abstract, "did")


visualize_means(dabstract_partywave_2020, "did")


ggsave(paste0(save_path, "figures/abstract_partisan_wave_2020.png"),
       width = 8, height = 4)

# Figure C3: Facts Longitude by Party/Wave  -----------------------------------

dfact_partywave_2020 <- estimate_means(df_fact, "did")

dfact_partywave_2024 <- estimate_means(dfR_fact, "subgroup_nowave", Party, weight) |> 
  mutate(Wave = "2024")

dfact_partywave_allyears <- rbind(dfact_partywave_2020, 
                                  dfact_partywave_2024)

visualize_means(dfact_partywave_allyears, "panel")

ggsave(paste0(save_path, "figures/fact_partisan_wave_allyears.png"),
       width = 8, height = 4)

# Figure C4: Abstract Longitude by Party/Wave  -----------------------------------


dabstract_partywave_2020 <- estimate_means(df_abstract, "did")

dabstract_partywave_2024 <- estimate_means(dfR_abstract, "subgroup_nowave", Party) |> 
  mutate(Wave = "2024")

dabstract_partywave_allyears <- rbind(dabstract_partywave_2020, 
                                      dabstract_partywave_2024)


visualize_means(dabstract_partywave_allyears, "panel")


ggsave(paste0(save_path, "figures/abstract_partisan_wave_allyears.png"),
       width = 8, height = 4)

# Figure C5: Facts/Forgone -----------------------------------------------------

df_fact_forgone <- df_fact %>% 
  filter(is.na(Error) & !is.na(Party)) %>% 
  mutate(Error = coalesce(Error, fact_dv)) %>% 
  mutate(fact_dv = "Main") %>% 
  estimate_means("did") %>% 
  mutate(Error = case_when(Error == "belief_vote_notcount" ~ "Belief vote wouldn’t be counted",
                           Error == "confused_vote" ~ "Confused about where or when to vote",
                           Error == "covid_fear" ~ "Fear of COVID-19",
                           Error == "fear_electionviolence" ~ "Fear of election day violence",
                           Error == "fear_intimidation" ~ "Fear they would be intimidated at polls",
                           Error == "line_toolong" ~ "Line was too long",
                           Error == "mail_noarrive" ~ "Mail ballot never arrived",
                           Error == "nothink_eligible" ~ "Didn't think they were eligible"))

df_fact_forgone %>% 
  filter(Wave %in% c("Pre", "Post") & Party %in% c("Democrat", "Republican")) %>% 
  group_by(Wave, Party) %>% 
  summarise(total = sum(estimate))

visualize_means(df_fact_forgone, "did")

ggsave(paste0(save_path, "figures/fact_forgone.png"),
       width = 10, height = 8)

# Figure C6 and C7 (pid3, Party-Wave) --------------------------------------------

# For Abstract
dabstract_pid3wave <- df_abstract %>% 
  left_join(df_respondents %>% 
              select(ResponseId, pid3_leaners)) %>%
  filter(!is.na(pid3_leaners)) %>% 
  estimate_means("subgroup", pid3_leaners) %>% 
  mutate(pid3_leaners = case_when(pid3_leaners == 1 ~ "Democrat",
                                  pid3_leaners == 2 ~ "Independent",
                                  pid3_leaners == 3 ~ "Republican")) %>% 
  rename(Party = pid3_leaners)

ggplot(dabstract_pid3wave)+ 
  geom_pointrange(aes(y = Error,
                      x = estimate,
                      color = Party, 
                      shape = Party,
                      xmin = conf.low,
                      xmax = conf.high),
                  position = position_dodge2(width = .75, reverse = T)) +
  theme_few() +
  scale_y_discrete(limits = rev) +
  scale_color_manual(values = c("#0015BC", "black", "#DE0100")) + 
  labs(y = NULL,
       x = "Estimated seriousness (scaled emotional reaction score)")  +
  theme(legend.position = "bottom") + 
  geom_vline(data = dabstract_pid3wave %>% filter(term != "(Intercept)"),
             aes(xintercept = 0),
             linetype = "dashed",
             color = "gray") +
  geom_vline(data = dabstract_pid3wave %>% filter(term == "(Intercept)"),
             aes(xintercept = .5),
             linetype = "dashed",
             color = "gray") +
  facet_grid(~ factor(Wave, levels = c("Pre", "Post", "Difference in Wave"),
                      labels = c("A) Pre", "B) Post", 
                                 "C) Post - Pre")),
             scales = "free_x") +
  ggh4x::facetted_pos_scales(x = list(
    scale_x_continuous(breaks = seq(0.5, 1, 0.1), limits = c(0.5, .9)),
    scale_x_continuous(breaks = seq(0.5, 1, 0.1), limits = c(0.5,.9)),
    scale_x_continuous(breaks = seq(-.05, 0.1, 0.05), limits = c(-.05, 0.1))
  ))

ggsave(paste0(save_path, "figures/abstract_pid3_leaners.png"),
       width = 8, height = 5)

# For Facts

dfact_pid3wave <- df_fact %>% 
  left_join(df_respondents %>% 
              select(ResponseId, pid3_leaners)) %>% 
  filter(!is.na(pid3_leaners)) %>% 
  estimate_means("subgroup", pid3_leaners) %>% 
  mutate(pid3_leaners = case_when(pid3_leaners == 1 ~ "Democrat",
                                  pid3_leaners == 2 ~ "Independent",
                                  pid3_leaners == 3 ~ "Republican")) %>% 
  rename(Party = pid3_leaners)

ggplot(dfact_pid3wave)+ 
  geom_pointrange(aes(y = Error,
                      x = estimate,
                      color = Party, 
                      shape = Party,
                      xmin = conf.low,
                      xmax = conf.high),
                  position = position_dodge2(width = .75, reverse = T)) +
  theme_few() +
  scale_y_discrete(limits = rev) +
  scale_color_manual(name = "Party", values = c("#0015BC", "black", "#DE0100")) + 
  labs(y = NULL,
       x = "Estimated votes (per 100 legitimate votes cast)")  +
  theme(legend.position = "bottom") + 
  geom_vline(data = dfact_pid3wave %>% filter(term != "(Intercept)"),
             aes(xintercept = 0),
             linetype = "dashed",
             color = "gray") +
  geom_vline(data = dfact_pid3wave %>% filter(term == "(Intercept)"),
             aes(xintercept = 50),
             linetype = "dashed",
             color = "gray") +
  facet_grid(~ factor(Wave, levels = c("Pre", "Post", "Difference in Wave"),
                      labels = c("A) Pre", "B) Post", 
                                 "C) Post - Pre")),
             scales = "free_x") +
  ggh4x::facetted_pos_scales(x = list(
    scale_x_continuous(breaks = seq(10, 50, 10), limits = c(10, 50)),
    scale_x_continuous(breaks = seq(10, 50, 10), limits = c(10,50)),
    scale_x_continuous(breaks = seq(-10, 10, 5), limits = c(-10, 10))
  ))

ggsave(paste0(save_path, "figures/fact_pid3_leaners.png"),
       width = 8, height = 5)

# Tables C1 and C2: Analysis X Political Interest -------------------------------------------


# alpha = .714 for engagement index
cronbach.alpha(df_respondents |> 
                 filter(!is.na(engagement_index)) |> 
                 select(politics_follow, sm_use,
                        sm_politics,
                        sm_share_politics))

df_fact_engagement <- left_join(df_fact, df_respondents |> 
                                  select(ResponseId, politics_follow, sm_use,
                                         sm_politics,
                                         sm_share_politics, engagement_index)) |> 
  mutate(PartyX = Party)

df_abstract_engagement <- left_join(df_abstract, df_respondents |> 
                                      select(ResponseId, politics_follow, sm_use,
                                             sm_politics,
                                             sm_share_politics, engagement_index))|> 
  mutate(PartyX = Party)

errors <- c("Fraudulent Votes", "Uncounted Votes", "Forgone Votes")

lm_politics_facts <- map(errors, ~ lm_robust(fact_values ~ politics_follow*Party, 
                                             data = df_fact_engagement,
                                             subset = Error == .x & fact_dv == "Main"))

lm_index_facts <- map(errors, ~ lm_robust(fact_values ~ engagement_index*PartyX, 
                                          data = df_fact_engagement,
                                          subset = Error == .x & fact_dv == "Main"))

texreg(c(lm_politics_facts, lm_index_facts), include.ci = FALSE)

make_texreg("table_engagement_facts",
            c(lm_politics_facts, lm_index_facts),
            custom.header = list("Follow Politics" = 1:3, "Index" = 4:6),
            custom.model.names = c(errors,
                                   errors),
            resize.width = TRUE,
            multiple.tasks = "normal",
            custom.coef.map = list("politics_follow" =  "Follow Politics",
                                   "PartyRepublican" =  "Republican ",
                                   "politics_follow:PartyRepublican" =  "Follow Politics $\\times$ Republican",
                                   "engagement_index" =  "Engagement Index",
                                   "PartyXRepublican" =  "Republican",
                                   "engagement_index:PartyXRepublican" =  "Engagement Index $\\times$ Republican",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Political and Social Media Engagement on Estimates of the Frequency of Election Errors, Study 1A",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 0--1, which is a
                                scaled emotional reaction score. Models estimated 
            using ordinary least squares regression, 
            with standard errors clustered by respondent. 
            Baseline of Democrat (compared to Republican). Follow Politics is measured on a 7-point Likert scale.
            The Engagement Index is an index measured on a 7-point Likert scale,
            comprised of how much the respondent follows politics, uses social media,
            uses social media for political news, and shares politics on social media."))


lm_politics_abstract <- map(errors, ~ lm_robust(abstract_values ~ politics_follow*Party, 
                                                data = df_abstract_engagement,
                                                subset = Error == .x & abstract_dv == "Main"))

lm_index_abstract <- map(errors, ~ lm_robust(abstract_values ~ engagement_index*PartyX, 
                                             data = df_abstract_engagement,
                                             subset = Error == .x & abstract_dv == "Main"))

texreg(c(lm_politics_abstract, lm_index_abstract), include.ci = FALSE)


make_texreg("table_engagement_abstract",
            c(lm_politics_abstract, lm_index_abstract),
            custom.header = list("Follow Politics" = 1:3, "Index" = 4:6),
            custom.model.names = c(errors, errors),
            resize.width = TRUE,
            multiple.tasks = "normal",
            custom.coef.map = list("politics_follow" =  "Follow Politics",
                                   "PartyRepublican" =  "Republican ",
                                   "politics_follow:PartyRepublican" =  "Follow Politics $\\times$ Republican",
                                   "engagement_index" =  "Engagement Index",
                                   "PartyXRepublican" =  "Republican",
                                   "engagement_index:PartyXRepublican" =  "Engagement Index $\\times$ Republican",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Political and Social Media Engagement on Estimates of Emotional Reaction Scale to Election Errors, Study 1A",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 0--1, which is a
                                scaled emotional reaction score. Models estimated 
            using ordinary least squares regression, 
            with standard errors clustered by respondent. 
            Baseline of Democrat (compared to Republican). Follow Politics is measured on a 7-point Likert scale.
            The Engagement Index is an index measured on a 7-point Likert scale,
            comprised of how much the respondent follows politics, uses social media,
            uses social media for political news, and shares politics on social media."))




# Section D: Study 2A Additional Analysis ----------------------------------

# Table D1 (Study 2A, Main Regression) --------------------------------------

lm1 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave + Party,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged",
                 clusters = ResponseId)

lm2 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Democrat",
                 clusters = ResponseId)

lm3 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Republican",
                 clusters = ResponseId)

lm4 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave + Type*Wave + Error*Wave + Intention*Wave + 
                   `Party Benefiting`*Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Democrat",
                 clusters = ResponseId)

lm5 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave  + Type*Wave + Error*Wave + Intention*Wave + 
                   `Party Benefiting`*Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Republican",
                 clusters = ResponseId)

make_texreg("table_study2",
            list(lm1, lm2, lm3, lm4, lm5),
            custom.header = list("Base" = 1:3, "Interactions" = 4:5),
            custom.model.names = c("All", "Democrats", "Republicans",
                                   "Democrats", "Republicans"),
            resize.width = TRUE,
            custom.coef.map = list("TypeMail" =  "Mail Ballot",
                                   "ErrorFraudulent" =  "Fraudulent Votes",
                                   "ErrorUncounted" =  "Uncounted Votes",
                                   "IntentionVillain" =  "Intentional Error (Villain)",
                                   "`Party Benefiting`Opposite Party" =  "Error Benefiting Opposite Party", 
                                   "WaveDuring" = "Wave -- During",
                                   "WavePost" =  "Wave -- Post",
                                   "PartyRepublican" =  "Republican",
                                   "TypeMail:WaveDuring"=  "Mail $\\times$ During",
                                   "TypeMail:WavePost" =  "Mail $\\times$ Post",
                                   "ErrorFraudulent:WaveDuring" =  "Fraudulent $\\times$ During",
                                   "ErrorUncounted:WaveDuring"=  "Uncounted $\\times$ During",
                                   "ErrorFraudulent:WavePost" =  "Fraudulent $\\times$ Post",
                                   "ErrorUncounted:WavePost" =  "Uncounted $\\times$ Post",
                                   "IntentionVillain:WaveDuring" =  "Intentional $\\times$ During",
                                   "IntentionVillain:WavePost" =  "Intentional $\\times$ Post",
                                   "`Party Benefiting`Opposite Party:WaveDuring" =  "Opposite Party $\\times$ During",
                                   "`Party Benefiting`Opposite Party:WavePost" =  "Opposite Party $\\times$ Post",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Election Error Vignettes on Feelings of Outrage, Study 2A",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 0--1. Models estimated 
            using ordinary least squares regression, 
            with standard errors clustered by respondent. 
            Baseline of in-person ballot (compared to mail),
            forgone votes (compared to fraudulent/uncounted),
            unintentional error (compared to intentional, committed by a villain),
            error benefiting own party (compared to error benefiting opposite party),
            pre-election survey wave (compared to during-
            and post-election survey waves)."))



# Table D2 --------------------------------------------------------------------
df_mechanism <- df %>% 
  dplyr::select(ResponseId, Wave, Party, matches("^(DV|RV|DN|RN).._belie|stori")) %>% 
  # This time, we do have to filter out independents because of the Party Benefiting variable
  filter(!is.na(Party)) %>% 
  # Each row becomes a scenario/reaction DV, filter out so each respondent is left with 15
  pivot_longer(cols = matches("^(DV|RV|DN|RN).._"), names_to = "name", 
               values_to = "scenario_values") %>% 
  filter(!is.na(scenario_values)) %>% 
  separate(col = name, into = c("scenario", "type"), sep = "_") %>% 
  pivot_wider(id_cols = ResponseId:scenario, names_from = type,
              values_from = scenario_values) %>% 
  mutate(believable = case_when(believable == "Not at all believable" ~ 1,
                                believable == "Slightly believable" ~ 2,
                                believable == "Somewhat believable" ~ 3,
                                believable == "Mostly believable" ~ 4,
                                believable == "Very believable" ~ 5,
                                TRUE ~ NA),
         storieslike = case_when(storieslike == "I did not see any stories like this" ~ 1,
                                 storieslike == "I saw a few stories like this" ~ 2,
                                 storieslike == "I saw several stories like this" ~ 3,
                                 storieslike == "I saw a lot of stories like this" ~ 4,
                                 TRUE ~ NA)) %>% 
  mutate(`Party Benefiting`= case_when(str_detect(scenario, "D") & Party == "Democrat" |
                                         str_detect(scenario, "R") & Party == "Republican" ~ "Own Party",
                                       TRUE ~ "Opposite Party")) %>% 
  mutate(Intention = case_when(str_detect(scenario, "V") ~ "Villain",
                               str_detect(scenario, "N") ~ "No Villain")) %>%
  mutate(Error = case_when(str_detect(scenario, "F") ~ "Forgone",
                           str_detect(scenario, "O") ~ "Fraudulent",
                           str_detect(scenario, "U") ~ "Uncounted")) %>% 
  mutate(Type = case_when(str_detect(scenario, "M") ~ "Mail",
                          str_detect(scenario, "P") ~ "In-Person")) %>% 
  mutate(`Party Benefiting` = fct_relevel(`Party Benefiting`, "Own Party", "Opposite Party"),
         Error = fct_relevel(Error, "Forgone", "Fraudulent", "Uncounted"),
         Type = fct_relevel(Type, "In-Person", "Mail"),
         Intention = fct_relevel(Intention, "No Villain", "Villain"))


df_mechanism %>% 
  summarise(believable = mean(believable, na.rm = TRUE),
            stories = mean(storieslike, na.rm = TRUE))

lm1 <- lm_robust(believable ~ Type + Error + Intention + `Party Benefiting` + 
                   Party, data = df_mechanism, cluster = ResponseId)

lm2 <- lm_robust(storieslike ~ Type + Error + Intention + `Party Benefiting` + 
                   Party, data = df_mechanism, cluster = ResponseId)

#texreg(list(lm1, lm2), include.ci = FALSE)

make_texreg("table_study2mechanism",
            list(lm1, lm2),
            custom.model.names = c("Believable", "Hear Stories"),
            custom.coef.map = list("TypeMail" =  "Mail Ballot",
                                   "ErrorFraudulent" =  "Fraudulent Votes",
                                   "ErrorUncounted" =  "Uncounted Votes",
                                   "IntentionVillain" =  "Intentional Error (Villain)",
                                   "`Party Benefiting`Opposite Party" =  "Error Benefiting Opposite Party", 
                                   "PartyRepublican" =  "Republican",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Vignette Features on Perceptions of the Vignettes, Study 2A",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 1 to 5 for believability
                                and 1 to 4 for hearing stories like the vignette. Models estimated 
            using ordinary least squares regression, 
            with standard errors clustered by respondent. 
            Baseline of in-person ballot (compared to mail),
            forgone votes (compared to fraudulent/uncounted),
            unintentional error (compared to intentional, committed by a villain), and
            error benefiting own party (compared to error benefiting opposite party)."))

# Table D3 ----------------------------------------------------------------

lm1 <- lm_robust(scenario_values ~ Type + Error + Intention*`Party Benefiting` + 
                   Wave + Party,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged",
                 clusters = ResponseId)

lm2 <- lm_robust(scenario_values ~ Type + Error + Intention*`Party Benefiting` + 
                   Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Democrat",
                 clusters = ResponseId)

lm3 <- lm_robust(scenario_values ~ Type + Error + Intention*`Party Benefiting` + 
                   Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Republican",
                 clusters = ResponseId)

texreg(list(lm1, lm2, lm3),
       include.ci = FALSE, digits = 3)


make_texreg("table_intentionXoutrage",
            list(lm1, lm2, lm3),
            custom.model.names = c("All", "Democrats", "Republicans"),
            scalebox = 1,
            custom.coef.map = list("TypeMail" =  "Mail Ballot",
                                   "ErrorFraudulent" =  "Fraudulent Votes",
                                   "ErrorUncounted" =  "Uncounted Votes",
                                   "IntentionVillain" =  "Intentional Error (Villain)",
                                   "`Party Benefiting`Opposite Party" =  "Error Benefiting Opposite Party", 
                                   "WaveDuring" = "Wave -- During",
                                   "WavePost" =  "Wave -- Post",
                                   "PartyRepublican" =  "Republican",
                                   "IntentionVillain:`Party Benefiting`Opposite Party" =  "Intentional $\\times$ Opposite Party",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Election Error Vignettes on Feelings of Outrage with Intentional $\\times$ Opposite Party Interactions, Study 2A",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 0--1. Models estimated 
            using ordinary least squares regression, 
            with standard errors clustered by respondent. 
            Baseline of in-person ballot (compared to mail),
            forgone votes (compared to fraudulent/uncounted),
            unintentional error (compared to intentional, committed by a villain),
            error benefiting own party (compared to error benefiting opposite party),
            pre-election survey wave (compared to during-
            and post-election survey waves)."))


# Table D4 (Triple Interaction) ----------------------------------------------------------------
lm1 <- lm_robust(scenario_values ~ Type + Error + Intention +`Party Benefiting` + 
                   Wave + Party + Error*Wave*Party,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged",
                 clusters = ResponseId)

lm2 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave + Error*Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Democrat",
                 clusters = ResponseId)

lm3 <- lm_robust(scenario_values ~ Type + Error + Intention + `Party Benefiting` + 
                   Wave + Error*Wave,
                 data = df_scenarios,
                 subset = scenario_dv == "feel_outraged" & Party == "Republican",
                 clusters = ResponseId)

texreg(list(lm1, lm2, lm3),
       include.ci = FALSE, digits = 3)


make_texreg("table_triple",
            list(lm1, lm2, lm3),
            scalebox = .8,
            custom.model.names = c("All", "Democrats", "Republicans"),
            custom.coef.map = list("TypeMail" =  "Mail Ballot",
                                   "ErrorFraudulent" =  "Fraudulent Votes",
                                   "ErrorUncounted" =  "Uncounted Votes",
                                   "IntentionVillain" =  "Intentional Error (Villain)",
                                   "`Party Benefiting`Opposite Party" =  "Error Benefiting Opposite Party", 
                                   "WaveDuring" = "Wave -- During",
                                   "WavePost" =  "Wave -- Post",
                                   "PartyRepublican" =  "Republican",
                                   "ErrorFraudulent:WaveDuring" =  "Fraudulent $\\times$ During",
                                   "ErrorUncounted:WaveDuring"=  "Uncounted $\\times$ During",
                                   "ErrorFraudulent:WavePost" =  "Fraudulent $\\times$ Post",
                                   "ErrorUncounted:WavePost" =  "Uncounted $\\times$ Post",
                                   "ErrorFraudulent:PartyRepublican" =  "Fraudulent $\\times$ Republican",
                                   "ErrorUncounted:PartyRepublican" =  "Uncounted $\\times$ Republican",
                                   "WaveDuring:PartyRepublican" =  "During $\\times$ Republican",
                                   "WavePost:PartyRepublican" =  "Post $\\times$ Republican",
                                   "ErrorFraudulent:WaveDuring:PartyRepublican" = "Fraudulent $\\times$ During $\\times$ Republican",
                                   "ErrorUncounted:WaveDuring:PartyRepublican" = "Uncounted $\\times$ During $\\times$ Republican",
                                   "ErrorFraudulent:WavePost:PartyRepublican" = "Fraudulent $\\times$ Post $\\times$ Republican",
                                   "ErrorUncounted:WavePost:PartyRepublican" = "Uncounted $\\times$ Post $\\times$ Republican",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Election Error Vignettes on Feelings of Outrage with Party $\\times$ Error $\\times$ Wave, Study 2A",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 0--1. Models estimated 
            using ordinary least squares regression, 
            with standard errors clustered by respondent. 
            Baseline of in-person ballot (compared to mail),
            forgone votes (compared to fraudulent/uncounted),
            unintentional error (compared to intentional, committed by a villain),
            error benefiting own party (compared to error benefiting opposite party),
            pre-election survey wave (compared to during-
            and post-election survey waves)."))







# Section E: Study 2B Additional Analysis ---------------------------------

# Table E1 (Wording Effects) ----------------------------------------------------------------

lm1 <- lm_robust(vignette_dv ~ vignette_interaction, data = dfR, weights = weight,
                 subset = Party == "Democrat" & vignette_wording == "wrong")
lm2 <- lm_robust(vignette_dv ~ vignette_interaction, data = dfR, weights = weight,
                 subset = Party == "Democrat" & vignette_wording == "serious")
lm3 <- lm_robust(vignette_dv ~ vignette_interaction, data = dfR, weights = weight,
                 subset = Party == "Republican" & vignette_wording == "wrong")
lm4 <- lm_robust(vignette_dv ~ vignette_interaction, data = dfR, weights = weight,
                 subset = Party == "Republican" & vignette_wording == "serious")
lm5 <- lm_robust(vignette_dv ~ vignette_interaction, data = dfR, weights = weight,
                 subset = Party == "Democrat")
lm6 <- lm_robust(vignette_dv ~ vignette_interaction, data = dfR, weights = weight,
                 subset = Party == "Republican")

make_texreg("table_study2b_wording",
            list(lm5, lm6, lm1, lm2, lm3, lm4),
            multiple.tasks = "normal",
            custom.header = list("Democrat" = 1, "Republican" = 2,
                                 "Democrat" = 3:4, "Republican" = 5:6),
            custom.model.names = c("Combined", "Combined",
                                   "Wrong", "Serious",
                                   "Wrong", "Serious"),
            resize.width = TRUE,
            custom.coef.map = list("(Intercept)" = "Constant", 
                                   "vignette_interactionForgone-Biden" =  "Biden Voter, Forgone Vote",
                                   "vignette_interactionForgone-Trump" =  "Trump Voter, Forgone Vote",
                                   "vignette_interactionFraudulent-None" =  "Unspecified Voter, Fraudulent Vote",
                                   "vignette_interactionFraudulent-Biden" =  "Biden Voter, Fraudulent Vote",
                                   "vignette_interactionFraudulent-Trump" =  "Trump Voter, Fraudulent Vote",
                                   "vignette_interactionUncounted-None" =  "Unspecified Voter, Uncounted Vote",
                                   "vignette_interactionUncounted-Biden" =  "Biden Voter, Uncounted Vote",
                                   "vignette_interactionUncounted-Trump" =  "Trump Voter, Uncounted Vote"),
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} The dependent variable ranges from 0--1. Models estimated 
            using ordinary least squares regression, 
            with robust standard errors. 
            Baseline of forgone votes (compared to fraudulent/uncounted) and
            no information on who they support (compared to supporting Biden/Trump)."),
            caption = "Effect of Vignettes on Seriousness of Election Errors by Wording, Study 2B",
            refresh = TRUE)

# Section F: Study 3 Additional Analysis ----------------------------------

# Table F1 ----------------------------------------------------------------

lm1_rating <- lm_robust(fair ~ fraud + disqualified + turnout + vignette + Party + new_rule,
                        data = df3a_conjoint,
                        clusters = ResponseId)

lm1_rating_interactions <- lm_robust(fair ~ fraud*Party + disqualified*Party + turnout*Party + vignette + new_rule,
                                     data = df3a_conjoint,
                                     clusters = ResponseId)


lm2_rating <- lm_robust(rules1 ~ fraud + fraud + vignette + Party + new_rule,
                        data = df3b_conjoint,
                        clusters = ResponseId)

lm2_rating_interactions <- lm_robust(rules1 ~ fraud*Party + disqualified*Party + vignette + new_rule,
                                     data = df3b_conjoint,
                                     clusters = ResponseId)


texreg(list(lm1_rating, lm1_rating_interactions,
            lm2_rating, lm2_rating_interactions), include.ci = FALSE, digits = 3)

make_texreg("table_study3rating",
            list(lm1_rating, lm1_rating_interactions, lm2_rating, lm2_rating_interactions),
            custom.header = list("Study 3A" = 1:2, "Study 3B" = 3:4),
            scalebox = 1,
            custom.model.names = c("Base", "Interactions", "Base", "Interactions"),
            custom.coef.map = list("fraud" = "Fraudulent Votes", 
                                   "disqualified" = "Uncounted Votes",
                                   "turnout" = "Turnout", 
                                   "vignette2" = "Vignette Order (2nd Vignette)",
                                   "vignette3" = "Vignette Order (3rd Vignette)",
                                   "vignette4" = "Vignette Order (4th Vignette)",
                                   "vignette5" = "Vignette Order (5th Vignette)",
                                   "PartyRepublican" = "Republican",
                                   "new_rule" = "New Rule",
                                   "fraud:PartyRepublican" = "Fraudulent $\\times$ Republican", 
                                   "PartyRepublican:disqualified" = "Uncounted $\\times$ Republican",
                                   "PartyRepublican:turnout" = "Turnout $\\times$ Republican",
                                   "(Intercept)" = "Constant"),
            caption = "Effect of Election Errors on Ratings of Each Election Rule, Study 3",
            custom.note = paste("\\item[\\hspace{-5mm}] %stars.",
                                "\\item[\\hspace{-5mm}] \\textit{Note:} Dependent variable ranges from a 0--1 scale, with 
                                1 indicating higher fairness ratings of each election rule.
       Models estimated using ordinary least squares regression, 
            with standard errors clustered by respondent."))


